using System;
using System.Runtime.InteropServices;
using System.Text;

namespace FridayShopping.Util
{
	/// <summary>
	/// Read values from registry.
	/// </summary>
	public class Registry
	{
		// base registry keys
		public enum RootKey : uint
		{
			ClassesRoot = 0x80000000,
			CurrentUser = 0x80000001,
			LocalMachine = 0x80000002,
			Users = 0x80000003
		}	

		class WinApi
		{
			#region Registry API imports

			[DllImport("coredll.dll")]
			public static extern int RegOpenKeyEx(
				uint hKey, string lpSubKey, int ulOptions, 
				int samDesired, ref uint phkResult);

			[DllImport("coredll.dll")]	
			public static extern int RegCloseKey(uint hKey);

			[DllImport("coredll.dll")]	
			public static extern int RegQueryValueEx(
				uint hKey, string lpValueName, int lpReserved, 
				out int lpType, byte[] lpData, ref int lpcbData);

			#endregion
		}
		
		// static class
		private Registry()
		{
		}

		/// <summary>
		/// Read string value from registry.
		/// </summary>
		static public string GetString(RootKey rootKey, string keyName, string valueName)
		{
			// result that is returned
			string result = "";

			try
			{
				// read specified registry location and convert to string
				byte[] data = GetValue(rootKey, keyName, valueName);
				if (data != null)
					result = UnicodeEncoding.Unicode.GetString(data, 0, data.Length);
			}
			catch
			{
				// return empty string if error occurs
			}
			return result.TrimEnd(new char[] {'\0'});				
		}

		/// <summary>
		/// Read int value from registry.
		/// </summary>
		static public int GetInt(RootKey rootKey, string keyName, string valueName)
		{
			// result that is returned
			int result = 0;
			
			try
			{
				// read specified registry location and convert to int
				byte[] data = GetValue(rootKey, keyName, valueName);
				if (data != null)
					result = System.BitConverter.ToInt32(data, 0);
			}
			catch
			{
				// return 0 if error occurs
			}
			
			return result;				
		}

		/// <summary>
		/// Read specified registry location. Returns data as a byte array
		/// and caller methods can convert to different types.
		/// </summary>
		static public byte[] GetValue(RootKey rootKey, string keyName, string valueName)
		{
			byte[] data = null;	// data that is returned
			uint hKey = 0;		// handle to reg key

			try
			{
				// open registry key
				if (WinApi.RegOpenKeyEx((uint)rootKey, keyName, 0, 0, ref hKey) == 0)
				{
					// get the size of the data
					int dataType;
					int dataSize = 0;
					WinApi.RegQueryValueEx(hKey, valueName, 0, out dataType, null, ref dataSize);

					// allocate room for data and read value
					if (dataSize != 0)
					{
						data = new byte[dataSize];
						WinApi.RegQueryValueEx(hKey, valueName, 0, out dataType, data, ref dataSize);
					}
				}
			}
			finally
			{
				if (hKey != 0)
					WinApi.RegCloseKey(hKey);
			}
						
			return data;
		}
	}
}
